package com.cloud.upms.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloud.common.core.constant.CommonConstants;
import com.cloud.common.core.exception.ProjectException;
import com.cloud.common.satoken.util.LoginUtil;
import com.cloud.api.upms.domain.dept.DeptAddUpdateReq;
import com.cloud.api.upms.enums.DeptExceptionEnum;
import com.cloud.api.upms.model.SysDept;
import com.cloud.api.upms.model.SysDeptPath;
import com.cloud.upms.dao.SysDeptMapper;
import com.cloud.upms.service.SysDeptPathService;
import com.cloud.upms.service.SysDeptService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Author:  xuanning
 * Date:    2023/2/9 16:35
 */
@Service
@AllArgsConstructor
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {

    private final SysDeptMapper sysDeptMapper;
    private final SysDeptPathService sysDeptPathService;


    @Override
    @Transactional
    public void addOrUpdate(DeptAddUpdateReq paramReq) {
        String deptName=paramReq.getDeptName();
        Long id=paramReq.getId();
        Long count=sysDeptMapper.selectCount(new LambdaQueryWrapper<SysDept>()
                .eq(SysDept::getDeptName,deptName)
                .eq(SysDept::getDelFlag, CommonConstants.ZERO)
                .ne(id!=null,SysDept::getId,id)
        );
        if(count>0){
            throw new ProjectException(DeptExceptionEnum.DEPTNAME_EXIST);
        }
        //1.处理组织信息
        SysDept dept=new SysDept();
        dept.setId(id);
        dept.setDeptName(deptName);
        dept.setSort(paramReq.getSort());
        dept.setPid(paramReq.getPid());
        this.saveOrUpdate(dept);

        //2.处理父子关系
        if(id==null){
            sysDeptPathService.addPath(dept);
        }else{
            SysDeptPath path = new SysDeptPath();
            path.setAncestor(dept.getPid());
            path.setDescendant(dept.getId());
            sysDeptPathService.updatePath(path);
        }

    }

    @Override
    @Transactional
    public void delete(Long id) {
        //有子菜单不能删除
        Long count=sysDeptMapper.selectCount(new LambdaQueryWrapper<SysDept>()
                .eq(SysDept::getPid,id)
                .eq(SysDept::getDelFlag, CommonConstants.ZERO)
        );
        if(count>0){
            throw new ProjectException(DeptExceptionEnum.LEAF_EXIST);
        }
        //删除部门
        sysDeptMapper.deleteById(id);
        //删除部门关系
        sysDeptPathService.deletePath(id);

    }

    @Override
    public List<Tree<Long>> listDept() {
        List<SysDept> list=sysDeptMapper.selectList(new LambdaQueryWrapper<SysDept>()
                .eq(SysDept::getDelFlag, CommonConstants.ZERO)
                .orderByDesc(SysDept::getSort)
        );
        return getTree(list);

    }

    @Override
    public List<Tree<Long>> listUserDept() {
        Long deptId=LoginUtil.getDeptId();
        if(LoginUtil.isAdmin()){
           return listDept();
        }
        List<SysDept> list=sysDeptMapper.getChildrenTree(deptId);
        return getTree(list);
    }


    private List<Tree<Long>> getTree(List<SysDept> list){
        return TreeUtil.build(list,0L,(node, tree)->{
            tree.setId(node.getId());
            tree.setName(node.getDeptName());
            tree.setParentId(node.getPid());
            //额外参数
            tree.putExtra("sort", node.getSort());
        });
    }
}
